package com.project.collectAPI.entity.MultiPois;


import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.collectAPI.comm.SpiderTools;
import com.project.collectAPI.entity.MeiTuan.MeituanGoods;
import com.project.collectAPI.entity.MeiTuan.SystemParam;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.Data;
import org.apache.http.client.config.RequestConfig;


import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

//批量多店同步商品
@Data
@JsonInclude(value=JsonInclude.Include.NON_NULL)
public class MultiPois {

    private String reqAPI="https://waimaiopen.meituan.com/api/v1/retail/multipoi/create";

    //统一的时间戳
    private String app_id;

    //统一的时间戳
    private Long timestamp;

    //签名
    private String signValue;


    //APP方门店id集合【必须】
    //门店id集合，APP方门店id，即商家中台系统里门店的编码。
    // 如商家在操作绑定门店至合作中心应用中时，未绑定三方门店id信息，则默认APP方门店id与美团门店id相同。
    // 最大支持100个门店编码。 此字段支持传多个门店id，以英文逗号隔开。
    // 如入参门店数量超出100个，则返回报错，本次调用全部失败。 按app维度，当前接口最高支持100个商品/秒的调用。
    //示例值： a001,a002,a003……
    private String app_poi_codes;


    private String app_spu_code;

    //商品名称
    private String name;


    // 单张图片： "2B86BE5A5C23786232DE37A4717E0D93"
    // 多张图片： "2B86BE5A5C23786232DE37A4717E0D93,86BE5A5C23786232DE37A4712324535,22BE5A5C23786232DE37A47123243567"
    private String picture;


    //详情图
    private String picture_contents;



    //分类id列表，用于同步商品多个分类信息。
    // (1)此字段上传末级商品分类，多个分类id以英文逗号隔开，最多支持上传5个分类信息。
    // (2)category_code_list与category_name、category_code、category_name_list字段必须且只能填写一个。
    // (3)如所传分类id任意一个在门店内不存在则本次同步失败，返回错误信息。
    // (4)所传分类下如已存在与当前商品名称重复的商品，则商品同步失败。
    // (5)更新逻辑下，所传分类信息将全部覆盖所有原分类；如本次更新失败，则商品原分类信息保持不变。
    // [ 创建时：category_code_list与category_name、category_code、category_name_list字段必须且只能填写一个 更新时非必填 ]
    // 示例值: ["1111","2222"]
    private String category_code_list;



    //分类名称列表，用于同步商品多个分类信息。
    // (1)此字段上传末级商品分类，多个分类名称以英文逗号隔开，最多支持上传5个分类信息，每个分类名称长度不能超过8个字符。
    // (2)category_name_list与category_name、category_code、category_code_list字段必须且只能填写一个。
    // (3)所传分类下如已存在与当前商品名称重复的商品，则本次同步失败。
    // (4)如所传分类名称在门店内不存在，则会直接新建此分类名称为一级分类。
    // (5)更新逻辑下，所传分类信息将全部覆盖所有原分类；如本次更新失败，则商品原分类信息保持不变。（6）不允许上传emoji等表情符。
    // [ 创建时：category_name_list与category_name、category_code、category_code_list字段必须且只能填写一个 更新时非必填 ]
    // 示例值: ["多分类a","多分类b"]
    private String category_name_list;


    //美团内部商品类目id：
    // (1)请先通过【retail/getSpTagIds 获取商品类目】接口获取平台最新的类目信息和末级类目id，本字段仅允许传入商品所属的末级类目id。
    // (2)如创建商品时商家未传递本字段，平台会进行类目自动推荐匹配。
    // （注意：系统自动匹配推荐类目时，可能存在匹配结果与实际商品应属类目不相符或匹配失败的情况，那么商品的类目信息可能不准确，也可能仍然为空。
    // 所以，强烈建议商家自行上传商品类目信息，减少和避免商品审核时被驳回，导致商品不能上架售卖的问题。）
    // [ 门店启用类目属性并且传递了销售或普通属性则  1.创建时必传，2.若商品创建时未传tag_id，更新时必传(只需传一次)。 门店未启用类目属性或未传递销售属性/普通属性则非必传。 ]
    // 示例值: 200001291
    private Long tag_id;



    /*
     * APP方商品的skus信息字符串，支持同时传多个sku信息。
     * 注：如果skus中传递box_num、box_price，以skus中信息为准；如未传递box_num、box_price，以外层参数为准。
     * 如果销售属性openSaleAttrValueList字段不为空，则多规格sku数量最大支持255个，若销售属性openSaleAttrValueList字段为空或未传递则多规格sku数量最大支持上限30个。
     * [ 否，更新时不可传递 ]
     *
     * */
    private List<skusObjects> skus;



    //skus子商品类
    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class skusObjects{

        //sku_id
        //是sku唯一标识码，字段信息限定长度不能超过40个字符。不允许上传emoji等表情符。
        //[ 必须 ] 实例值:01010
        private String sku_id;

        //sku的规格名称。字段信息限定长度不能超过20个字符。不允许上传emoji等表情符。
        // 如创建单规格商品，本参数可不传；如创建多规格商品，本参数必传。 更新时传递EMPTY_VALUE支持置空。
        //示例值： 1000W
        //[ 创建时门店启用类目属性且skus中传递了销售属性则为非必填(会自动根据销售属性组合其规格)，其余情况参考字段描述里规则。 更新商品时，本参数非必填。 ]
        private String spec;

        //商品sku的售卖单位。注意：商户端后台已去掉售卖单位字段，默认单位为“份”。本参数不建议使用了，请无需上传，后续接口规则也会全部默认使用“份”。
        // 参数逻辑： 1.如此字段有值，优先取此处值。如入参符合枚举值（枚举值有：份、盒、件、箱、袋、筐、双、捆、把、提、包、个），取入参值；如入参不符合枚举值，则默认为“份”。
        // 2.如此字段无值而外层SPU字段有值，取外层值。外层入参符合枚举值（枚举值有：份、盒、件、箱、袋、筐、双、捆、把、提、包、个），取入参值；如外层入参不符合枚举值，则默认为“份”。
        // 3.如此字段和外层SPU字段都没传，取系统默认值“份”。
        //[ 选填 ]
        //private String unit;

        //一个订单中此商品sku的最小购买量：
        // 1.大等于1的正整数。
        // 2.如此字段有值，优先取此处值。
        // 3.如此字段无值而外层SPU字段有值，取外层值。
        // 4.如此字段和外层SPU字段都没传，取系统默认值"1"。
        //[ 选填 ] 示例值：2
        //private Integer min_order_count;

        //为sku的价格，单位是元，最多支持2位小数，不能为负数；字段信息最大允许上传50000。
        //[ 创建时必填 ] 示例值：55
        private String price;

        //sku的库存量，不能为负数或小数；传"*"表示设置商品库存为平台当前允许的最大值99999。
        //[ 创建时必填 ] 示例值：10
        private String stock;

        //为sku的商品包装上的条形码编号，UPC/EAN码；字符长度8位或者13位；字符内容范围是中文、字母、数字。
        // 特殊字段逻辑： 1.新增或更新商品时如无upc字段则可传"no_upc"，跳过校验。
        // 2.更新时若想置空upc需传入EMPTY_VALUE支持置空。
        //[ 选填 ] 示例值：1234567
        private String upc;


        //表示sku的料位码，商品在商家线下货架的位置；字段信息限定长度不超过40个字符。
        // 不允许上传emoji等表情符。
        // 更新时传递EMPTY_VALUE支持置空。
        //private String location_code;



        //表示sku的重量数值信息，最多支持两位小数。
        // 注：重量信息与重量单位的组合，不得超过200千克。重量单位为“克”“毫升”时，重量信息不能为小数。
        // 重量单位为“磅”时，重量信息不能为小数且不得超过440。重量单位为“斤”时，重量信息不能超过400斤。重量单位为“两”时，重量信息不能超过4000两。
        // [ 创建时必填，与weight至多填写一个 ]  示例值：1.12
        private String weight_for_unit;


        //表示sku的重量数值单位，枚举值如下： 1."克(g)" 2."千克(kg)" 3."毫升(ml)" 4."升(L)" 5."磅" 6."斤" 7."两"。
        //[ 创建时必填 ] 示例值：升(L)
        private String weight_unit;

        //包装费老计费规则，表示：商品sku单件需使用打包盒的数量，不能为负数或小数，需在0-100之间。
        // 1.创建时，传了skus信息，则本参数box_num如不传则默认为1。
        // 2.更新时，如不传则取外层box_num值，如外层没有传，则保持原值不变。
        // 3.医药商家暂不支持设置包装费，无论上传多少，系统均默认以0元为准。 注：如原规则为阶梯计费，更新时仅传了box_price，则本参数默认的原值为兼容值1。则本参数默认的原值为兼容值1。
        //[ 选填 ] 示例值：1
        //private String box_num;


        //包装费老计费规则，表示：商品sku单个打包盒的价格，单位是元，不能为负数，需在0-100之间。
        // 1.创建时，传了skus信息，则本参数box_price如不传则默认为0。
        // 2.更新时，如果没传包装费信息（新/旧字段），则取外层box_price值，如外层没有传，则保持原值不变。
        // 注：如原规则为阶梯计费，更新时仅传了box_num，则本参数默认的原值为原ladder_box_price的值。
        // 3.商品包装费box_num*box_price最大不能高于2元，如果上传数据结果大于2元，默认以2元为准。
        // 4.医药商家暂不支持设置包装费，无论上传多少，系统均默认以0元为准。
        //[ 选填 ] 示例值：0
        //private String box_price;


        //包装费阶梯计价规则，表示：每M件商品收取N元包装费中的M。
        // 1.仅支持传[1,100]的整数。
        // 2.ladder_box_num和ladder_box_price要么同时传，要么均不传。
        // 3.ladder_box_num和ladder_box_price的组合与box_num或box_price互斥。
        // 4.医药商家暂不支持设置包装费，无论上传多少，系统均默认以0元为准。
        //[ 选填 ] 示例值：3
        //private String ladder_box_num;

        //包装费阶梯计价规则，表示：每M件商品收取N元包装费中的N。
        // 1.仅支持传[0,2]，最多支持两位小数。
        // 2.ladder_box_num和ladder_box_price要么同时传，要么均不传。
        // 3.ladder_box_num和ladder_box_price的组合与box_num或box_price互斥。
        // 4.医药商家暂不支持设置包装费，无论上传多少，系统均默认以0元为准。
        //[ 选填 ] 示例值：1.5
        //private String ladder_box_price;


        //商品销售属性
        // 1.仅支持类目属性的品类下的门店传递后有值。
        // 2.销售属性列表可通过 category/attr/list、category/attr/value/list 接口获取。
        // 3.上传销售属性值ID、值value支持自定义。
        //[ 选填 ]
        //private List<SaleObject> openSaleAttrValueList;


        @Data
        public static class SaleObject{

            //销售属性id，不支持自定义
            //示例值：100002086
            private Long attrId;

            //属性名称
            private String attrName;

            private List<Object> valueList;

            //销售属性值id。当属性值录入方式为文本时，该参数无需上传；若该销售属性可扩展则支持自定义：
            // 1.负值
            // 2.同一个商品的同一个销售属性内唯一
            //private Long valueId;

            //销售属性值，支持自定义
            //示例值："红"
            //private String value;

        } //SaleObject End

    } //skusObjects End




    //商品普通属性的json字符串
    // 1.仅支持类目属性的品类下的门店传递后有值。
    // 2.普通属性列表可通过 category/attr/list、category/attr/value/list 接口获取。
    // 3.该普通属性可扩展则支持自定义值id和值value。
    //示例值
        /*
                [{
                    "attrId": 100002441,
                    "attrName": "品牌",
                    "valueList": [{
                        "valueId": 1018448,
                        "value": "小西瓜"
                    }]
                }, {
                    "attrId": 100002137,
                    "attrName": "产地",
                    "valueList": [{
                        "valueId": 130600,
                        "value": "保定"
                    }]
                }, {
                    "attrId": 100002412,
                    "attrName": "普通属性",
                    "valueList": [{
                        "valueId": 100001545,
                        "value": "2"
                    }]
                }, {
                    "attrId": 100002442,
                    "attrName": "大小",
                    "valueList": [{
                        "valueId": 100001574,
                        "value": "大"
                    }, {
                        "valueId": 100001576,
                        "value": "小"
                    }]
                }]
        * */
    // [ 若美团内部类目tag_id对应的标准普通类目属性有必填项，则创建时必填，否则创建/更新均非必填 ]
    private List<MeituanGoods.fooddata.commonAttrClass> common_attr_value;
    @Data
    public static class commonAttrClass{
        //普通属性Id
        //示例值： 10005
        private Long attrId;
        //普通属性名称
        //示例值： 适用对象
        private String attrName;
        private List<MeituanGoods.fooddata.commonAttrClass.valueObj> valueList;
        public static class valueObj{
            //普通属性值Id，当属性值录入方式为文本时，该参数无需上传；若该普通属性可扩展则支持自定义 1.负值 2.同一个商品的同一个普通属性内唯一
            //示例值： 25
            public Long valueId;
            //普通属性值名称(与普通属性值Id一一对应)，支持自定义。
            //示例值： 老人
            public String value;
        }
    } //commonAttrClass End


    //商品限购详情【必填】
    //{"limitSale":true,"type":1,"begin":"20200216","count":10.6,"end":"20200221"}
    private String limit_sale_info;
    //*****************************  需要合并的字符串<<Start>>   *******************************
    //需要合并的字符串
    //【必填】
    //是否限制购买数量：
    // (1)字段取值范围：1.true-开启；false-关闭。
    // (2)如开启限制，则对SPU下所有SKU生效，每个SKU均按设置规则执行限购。
    // (3)如入参选择“不限制”，则后续参数入参也无效。
    // (4)如入参选择“限制”，则开启单个买家限购功能。
    private Boolean limitSale=false;

    //【如限购开启则必填】
    //限购规则：
    // 1-限制下单顾客每X天限购数量，X为frequency，不传默认为1；
    // 2-限制整个周期内下单顾客限购数量。
    //private int type;

    //限购循环天数： 最大31，最小1。
    // 示例值： 1
    //private int frequency;

    //【如限购开启则必填】
    // 示例值： 20200216
    // 限购开始日期： 开始时间不得早于当前日期的7天前。
    //private String begin;

    //【如限购开启则必填】
    // 示例值： 20200221
    // 限购结束日期： 结束日期不得早于开始日期，且与开始日期相距不得超出90天。
    //private String end;

    //【如限购开启则必填】
    // 示例值： 10
    // 限购数量： (1)字段范围：整数，最小为1。(2)如入参为小数，则向下取整（例如：入参数量为2.8，最终取2）。
    //private int count;
    //*****************************  需要合并的字符串<<End>>   *******************************


    /*批量创建接口签名*/
    public String getSign() throws Exception {
        SystemParam systemParam=new SystemParam();
        Map<String,Object> map=new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        //System.out.println("getSign() SystemParam.timestamp===>"+timestamp);
        map.put("timestamp",timestamp);  //timestamp尽量统一用一次
        map.put("app_id",systemParam.getAppId());
        map.put("app_poi_codes",app_poi_codes);
        map.put("app_spu_code",app_spu_code);
        map.put("name",name);
        String skus2JSON = objectMapper.writeValueAsString(skus); // 字符串转json
        map.put("skus",skus2JSON);
        map.put("tag_id",tag_id);
        map.put("category_code_list",category_code_list);
        map.put("picture",picture);
        String comAttr2JSON = objectMapper.writeValueAsString(common_attr_value); // 字符串转json
        map.put("common_attr_value",comAttr2JSON);
        map.put("limit_sale_info",limit_sale_info);
        return systemParam.getSign(map,reqAPI); //获取签名
    }


    /*请求*/
    public String startMulitPois() throws Exception {
        SystemParam systemParam=new SystemParam();
        ObjectMapper objectMapper = new ObjectMapper();
        //Post请求2
        Map<String, String> applicationParamsMap=new HashMap<>();
        applicationParamsMap.put("app_id",systemParam.getAppId());
        applicationParamsMap.put("timestamp",String.valueOf(timestamp));
        applicationParamsMap.put("sig",signValue);
        applicationParamsMap.put("app_poi_codes",app_poi_codes); //批量店铺id
        applicationParamsMap.put("app_spu_code", app_spu_code);
        applicationParamsMap.put("name",name.replace(" ","+"));
        String skus2JSON = objectMapper.writeValueAsString(skus); // 字符串转json
        applicationParamsMap.put("skus", skus2JSON);
        applicationParamsMap.put("category_code_list", category_code_list);
        applicationParamsMap.put("picture",picture);
        applicationParamsMap.put("tag_id", tag_id.toString());
        String comAttr2JSON = objectMapper.writeValueAsString(common_attr_value); // 字符串转json
        applicationParamsMap.put("common_attr_value",comAttr2JSON);
        applicationParamsMap.put("limit_sale_info",limit_sale_info);

        System.out.println("请求参数:");
        System.out.println(applicationParamsMap);

        RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
        // ConnectTimeout:连接超时.连接建立时间，三次握手完成时间.
        requestConfigBuilder.setConnectTimeout( 30000* 1000);
        String res= SpiderTools.requestOfPost(reqAPI, applicationParamsMap,requestConfigBuilder);
        System.out.println("startMulitPoisCreate多店同步数据结果================>");
        System.out.println(res);
        JSONObject rct=JSONObject.parseObject(res);
        String data= (!Objects.isNull(rct.get("data")))?rct.getString("data"):null;
        return data;
    }


} //Class End
